#include <iostream>
#include <fstream>
#include <string>
#include "errors.h"
#include "tokenizer.h"
#include "parser.h"
#include "cmd.h"

using namespace std;

/* define filename placed in directory $(SolutionDir)tests\tests\ as _DEBUG_ if
   you want to debug particular set of data
*/
//#define _DEBUG_ "C:\\Users\\Kravitz\\Documents\\Visual Studio 2008\\Projects\\ccompiler\\tests\\tests\\expressions parser2\\12.tst"

int main(int argc, char *argv[])
{
	string filename;
#ifdef _DEBUG_
	filename = _DEBUG_;
#else
	try
	{
		cmd::ParseCmd(argc, argv);
	}
	catch(CCompiler::Errors::CmdOptionsError)
	{
		cout << "Wrong command string" << endl;
	}
	if(cmd::NeedToPrintHelp())
	{
		cout << "CCompiler by Kravtsov Dmitriy" << endl;
		cout << "Implemented components:" << "tokenizer, expressions parser" << endl;
		cout << "To use type: ccompiler.exe <filename> [options]" << endl;
		cout << "Available options are:" << endl;
		cout << "\t--tokenizer-only - use only tokenizer" << endl;
		cout << "\t--expressions-parser-only - use only expressions parser" << endl;
	}
    else
    {
		filename = cmd::GetFilename();
#endif
        try
        {
			ifstream file(filename.c_str());
            CCompiler::Tokenizer tokenizer(file);
			if(cmd::LexerOptionEnabled())
			{
				CCompiler::Token t = tokenizer.GetCurToken();
				do
				{
					if(t.GetTokenType() == CCompiler::ttEof) break;
					cout << t;
					if(t.GetTokenType() == CCompiler::ttError) break;
					t = tokenizer.NextToken();
				} while(true);
			}
			else if(cmd::ParseExpressionsOptionEnabled())
			{
				CCompiler::BasicParser parser(tokenizer);
				while(tokenizer.GetCurToken().GetTokenType() != CCompiler::ttEof)
				{
					CCompiler::SynNode *expr = parser.ParseExpression();
					expr->print(std::cout);
				}
			}
			else
			{
				CCompiler::BasicParser2 parser(tokenizer);
				while(tokenizer.GetCurToken().GetTokenType() != CCompiler::ttEof)
				{
					CCompiler::SynNode *expr = parser.ParseExpression2();
					expr->print(std::cout);
				}
			}
        }
        catch(CCompiler::Errors::BrokenStream)
        {
            cout << "Unable to read from file " << filename;
        }
		catch(CCompiler::Errors::SyntaxError e)
		{
			cout << e;
		}
		catch(CCompiler::Errors::TokenError e)
		{
			cout << e;
		}
		catch(CCompiler::Errors::EndOfFile)
		{}
#ifndef _DEBUG_
	}
#endif
}
